package dp05.leertaak1.server;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;

import dp05.leertaak1.server.protocol.Protocol;

public class ClientHandler implements Runnable
{
    public enum Action {
        CLOSE, COMMIT, GET, INSERT, REDO, TOTAL, UNDO
    }

    private Socket client;
    private BufferedReader reader;
    private PrintWriter writer;
    private Protocol protocol;

    public void setProtocol(Protocol protocol)
    {
        this.protocol = protocol;
    }

    public ClientHandler(Socket client, Protocol protocol)
    {
        this.protocol = protocol;
        this.client = client;

        try
        {
            reader = new BufferedReader(new InputStreamReader(client.getInputStream()));
            writer = new PrintWriter(client.getOutputStream(), true);
        } catch (IOException e)
        {
            e.printStackTrace();
        }
    }

    @Override
    public void run()
    {
        while (clientIsOpen())
        {
            try
            {
                String fromClient = reader.readLine();
                if (fromClient != null)
                {
                    String message = processRequest(fromClient);
                    writer.println(message);
                    
                    if(fromClient.equalsIgnoreCase("close"))
                    {
                        this.close();
                        Server.removeClient(this);
                    }
                }

            } catch (IOException e)
            {
                e.printStackTrace();
            }

        }
    }

    private void close()
    {
        try
        {
            writer.close();
            reader.close();
            client.close();
        } catch (IOException e)
        {
            e.printStackTrace();
        }
    }

    private String processRequest(String request)
    {
        request = request.trim();
        String[] parameters = request.split(" ");

        Action currentAction = stringToCommand(parameters[0]);
        String message = protocol.createAndExecuteCommand(currentAction, parameters);
        
        return message;
    }

    private Action stringToCommand(String c)
    {
        for (Action command : Action.values())
        {
            if (command.name().equalsIgnoreCase(c))
            {
                return command;
            }
        }
        return null;
    }

    private boolean clientIsOpen()
    {
        return client.isConnected() && !client.isClosed();
    }

    public Protocol getProtocol()
    {
        return protocol;
    }

}